package com.yueqian.framework.config;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import cn.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Configuration
public class MqConfig {

	@Resource
	private RabbitTemplate rabbitTemplate;

	/**
	 * 确认模式：
	 * 步骤：
	 * 1. 确认模式开启：ConnectionFactory中开启publisher-confirms="true"
	 * 2. 在rabbitTemplate定义ConfirmCallBack回调函数
	 */
	@PostConstruct
	public RabbitTemplate config() {
		//2. 定义回调 **
		rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
			/**
			 *
			 * @param correlationData 相关配置信息
			 * @param ack   exchange交换机 是否成功收到了消息。true 成功，false代表失败
			 * @param cause 失败原因
			 */
			@Override
			public void confirm(CorrelationData correlationData, boolean ack, String cause) {
				if (ack) {
					if (ObjectUtil.isNotEmpty(correlationData)) {
						//接收成功
						log.info("消息已发出，成功到达交换机。消息id={}", correlationData.getId());
					} else {
						log.info("消息已发出，成功到达交换机");
					}
				} else {
					//接收失败
					//做一些处理，让消息再次发送。
					if (ObjectUtil.isNotEmpty(correlationData)) {
						log.warn("消息已发出，但未到达交换机。消息id={}，原因是：{}", correlationData.getId(), cause);

					} else {
						log.warn("消息已发出，但未到达交换机");
					}
				}
			}
		});
		rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback() {
			@Override
			public void returnedMessage(ReturnedMessage returnedMessage) {
				log.error("消息未被路由到队列，replyCode={}, replyText={}, exchange={}, routingKey={}, msg={}",
						returnedMessage.getReplyCode(), returnedMessage.getReplyCode(), returnedMessage.getExchange(), returnedMessage.getRoutingKey(), returnedMessage.getMessage());
			}
		});

		return rabbitTemplate;
		//3. 发送消息
//				rabbitTemplate.convertAndSend("test_exchange_confirm111", "confirm", "message confirm....");
	}

	@Bean
	public TopicExchange topicExchange() {
		return ExchangeBuilder.topicExchange("topic_exchange")
					   //设置交换机为持久化的，重启也不消失。
					   //但其实可以不设置，因为交换机默认就是持久化的
					   .durable(true)
					   .build();
	}

	@Bean
	public Queue topicQueue() {
		return QueueBuilder
					   //使用durable("队列名称")方法  创建的就是持久化队列
					   .durable("topic_queue")
					   .build();
	}

	@Bean
	public Binding demoQueueBinding(Queue topicQueue, TopicExchange topicExchange) {
		return BindingBuilder.bind(topicQueue).to(topicExchange).with("topic");
	}
}
